iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
自我挑戰組

我與 React 的 30天系列 第 19

Day 19 useMemo 請問你跟 React.memo 有關係嗎?

  • 分享至 

  • xImage
  •  

我想看到大家第一次看到 usememo 都會跟我有一樣的疑問

請問 useMemoReact.memo 是一樣的東西嗎,用法一樣嗎?,這兩個名稱一樣,用法一定差不多拉!

但是其實用法是不一樣的,雖然從昨天介紹的 React.memouseCallback 到今天要介紹的 useMemo

出現的目的都是為了優化你的 React 專案,不要讓沒有變動的值,以及狀態去做重複的渲染,但是怎麼用,用在哪,使用時機是什麼,這就是我們要去了解的,好了說了那麼多廢話,就讓我們開始今天的主題 useMemo

每次渲染都需要大量運算怎麼辦?

想像一下我們在 React 中需要大量運算,或是打 API 獲取資料後需要執行迴圈時將我想要的資料呈現在畫面上,但若是資料量非常大的時候,可能會跑回圈跑到死,

那若是每次因為 Component 狀態的改變每次都要重新渲染,那不就是要一直重新計算,不斷地重複計算一樣的東西

讓我們用下面這個例子來看看

import { useState } from "react"
import "./index.css"

const SlowComponent = () =>{
  let start = 0;
  let end = 0;
  const [count, setCount] = useState(0)

  const slowCountFunction = () => {
    for (let i = 0; i < 10000000000; i++) {
    }
    console.log("大量計算好久....");
    return "每次資料都一樣"
  }

  start = new Date().getTime()
  slowCountFunction()
  end = new Date().getTime()
  
  console.log(((end - start) / 1000 + "sec"))

  const changeHandler = () =>{
    setCount(perv => perv + 1)
  }



  return (
    <>
      <div className="container">
        <div>
          <button onClick={changeHandler}>點擊加一</button>
        </div>
        <div className="size">現在的 {count} 次數</div>
      </div>  
      <div>
        {slowCountFunction()}
      </div>
    </>
  )
}

export default SlowComponent

我們用一個比較極端的例子,在這個例子中我們可以想像slowCountFunction,是在做獲取資料的動作,但是因為我每次點擊 button執行 setCount,所以造成 count 的改變,這時 React 也會重新渲染組件,所以每次都會需要龐大的運算

哇!每次都需要這麼長的時間才能計算完成,我是使用者應該會瘋掉,

所以這時一樣,我們今天的主角出現了 useMemo

大量的運算讓我來記住 useMemo

useMemo 會讓 React 記住 function 的回傳值,
如果第二個參數 dependencies array 中的變數都沒有改變的話,React.useMemo 將會沿用上次的回傳值。

OK!! 好像看完也是不知道怎麼用對吧!
來吧上例子~

import { useState, useMemo } from "react"
import "./index.css"

const SlowComponent = () =>{
  let start = 0;
  let end = 0;
  const [count, setCount] = useState(0)
  const [data, setData] = useState(true)

  start = new Date().getTime()

  const slowCountFunction = () => {
    for (let i = 0; i < 10000000000; i++) {
    }
    console.log("大量計算好久....");
    return "每次資料都一樣"
  }
  
  const aa = useMemo(() => {
    return slowCountFunction()
  } )

  end = new Date().getTime()

  
  console.log(((end - start) / 1000 + "sec"))

  const changeHandler = () =>{
    setCount(perv => perv + 1)
  }



  return (
    <>
      <div className="container">
        <div>
          <button onClick={changeHandler}>點擊加一</button>
        </div>
        <div className="size">現在的 {count} 次數</div>
      </div>  

      <button onClick={() => {setData(!data)}}>按我才會進行龐大運算</button>
      {data? "data 是 true" : "data 是 false" }
      <div>
        {slowCountFunction}
      </div>
    </>
  )
}

export default SlowComponent

在這邊我使用 useState 宣告了另一個變數 data,並且新做了一個按鈕來改變 data 的狀態,

const [data, setData] = useState(true)

然後將我們需要龐大計算的 function 用 useMemo 包起來,並且將第二個參數 dependencies array 放入 data,所以只有 data 改變時,才會進行計算,所以可以看到我點擊上面的按鈕畫面不會進行 useMemo 內的運算,點擊下面的按鈕,改變 data 的狀態才會進行龐大運算

這樣就不會被其他的變數所的變數所影響,

useMemo 會運用在你需要記住一個龐大計算後的結果

const slowCountFunction = useMemo(()=> {
  for (let i = 0; i < 10000000000; i++) {
  }
  console.log("大量計算好久....");
  return "每次資料都一樣"
},[data])

小結

今天介紹了 useMemo,一開始我也會以為他和 React.memo 有關係,但是實際了解之後,就知道他們的不同之處,明天會將這幾天介紹的
memouseCallbackuseMemo,做個統整,謝謝大家收看!


上一篇
Day 18 React.memo 聽說你很猛啊,useCallback 表示?
下一篇
Day 20 memo vs useCallback vs useMemo
系列文
我與 React 的 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言